package com.appcenter.application.service;

import com.appcenter.application.dto.OrgUsers.OrgDto;
import com.appcenter.application.dto.OrgUsers.ResultOrgUserDto;
import com.appcenter.application.input.OrgUser.*;
import com.appcenter.application.mapper.AppsMapper;
import com.appcenter.application.mapper.OrgUsersMapper;
import com.appcenter.application.mapper.OrgsMapper;
import com.appcenter.application.mapper.UsersMapper;
import com.appcenter.application.model.Apps;
import com.appcenter.application.model.OrgUsers;
import com.appcenter.application.model.Orgs;
import com.appcenter.application.model.Users;
import com.appcenter.application.output.OrgUser.*;
import com.appcenter.jz.Unit.ObjectUnit;
import com.appcenter.jz.config.ErrorJsonResult;
import com.appcenter.jz.page.PagedResult;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.apache.catalina.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import tk.mybatis.mapper.entity.Example;
import tk.mybatis.mapper.util.Sqls;

import java.util.*;

import static org.apache.http.util.TextUtils.isBlank;

@Service
public class OrgUserService {
    @Autowired
    OrgsMapper orgsMapper;
    @Autowired
    AppsMapper appsMapper;

    @Autowired
    OrgUsersMapper orgUsersMapper;

    @Autowired
    UsersMapper usersMapper;

    public CreateOrgUserOutput CreateOrgUser(CreateOrgUserInput input) {
        CreateOrgUserOutput output = new CreateOrgUserOutput();


        Example example = new Example(Users.class);
        Example.Criteria criteriau = example.createCriteria();
        criteriau.andEqualTo("UserCode", input.getItem().getUserCode());

        int userCount = usersMapper.selectByExample(example).size();
        //int userCount=1;
        Users user = null;
        if (userCount > 0) {
            //如果该用户与该部门已经有关系  则提示部门人员重复  阻止添加

            Example exampleOrgUser = new Example(OrgUsers.class);
            Example.Criteria criteria = exampleOrgUser.createCriteria();

            if (input.getItem().getAppCode() == null) {
                criteria.andIsNull("AppCode");
            } else {
                criteria.andEqualTo("AppCode", input.getItem().getAppCode());
            }
            criteria.andEqualTo("OrgId", input.getItem().getOrgId());
            criteria.andEqualTo("UserCode", input.getItem().getUserCode());

            int orgUserCount = orgUsersMapper.selectByExample(exampleOrgUser).size();
            if (orgUserCount > 0) {

                throw new ErrorJsonResult("1000031", "该部门已存在此用户信息");
            } else {
                user = usersMapper.getUsersByUserCode(input.getItem().getUserCode());
            }
        } else {
            throw new ErrorJsonResult("1000031", "用户账号不存在");
        }
        String uuid = UUID.randomUUID().toString().replace("-", "").toLowerCase();
        OrgUsers orgUser = new OrgUsers();
        orgUser.setId(uuid);
        orgUser.setOrgId(input.getItem().getOrgId());
        orgUser.setOrgCodePath(orgsMapper.selectByPrimaryKey(input.getItem().getOrgId()).getOrgCodePath());
        orgUser.setUserId(user.getId());
        orgUser.setUserCode(user.getUserCode());
        orgUsersMapper.insertSelective(orgUser);
        output.setItem(orgUser);
        return output;
    }

    public DeleteOrgUserOutput DeleteOrgUser(DeleteOrgUserInput input) {
        DeleteOrgUserOutput output = new DeleteOrgUserOutput();
        //删除部门成员信息
        orgUsersMapper.deleteByPrimaryKey(input.getItem().getId());
        return output;
    }

    public EditOrgUserOutput EditOrgUser(EditOrgUserInput input) {
        EditOrgUserOutput output = new EditOrgUserOutput();

        Users user = usersMapper.getUsersByUserCode(input.getItem().getUserCode());
        if (user == null) {
            throw new ErrorJsonResult("1000031", "未找到用户信息");
        }

        OrgUsers orguser = orgUsersMapper.selectByPrimaryKey(input.getItem().getId());

        if (orguser != null) {
            orguser.setOrgId(input.getItem().getOrgId());
            orguser.setOrgCodePath(orgsMapper.selectByPrimaryKey(input.getItem().getOrgId()).getOrgCodePath());
            orguser.setUserId(user.getId());
            orguser.setUserCode(user.getUserCode());
            orgUsersMapper.updateByPrimaryKey(orguser);
        }
        output.setItem(orguser);
        return output;
    }

    public GetOrgUsersOutput GetOrgUsers(GetOrgUsersInput input) {
        GetOrgUsersOutput output = new GetOrgUsersOutput();
        if (input.getAppCode() == null || input.getAppCode().length() == 0) {
            input.setAppCode(null);
        }
        if (input.getOrgId() != null) {
            Orgs org = orgsMapper.selectByPrimaryKey(input.getOrgId());
            input.setOrgCodePath(org.getOrgCodePath());
        }
        PageHelper.startPage(input.getPage().getPageNo(), input.getPage().getPageSize(), "Id desc");
        //List<Apps> ls = AppMapper.SearchApps(input);
        List<ResultOrgUserDto> ls = orgUsersMapper.searchOrgUsers(input);
        PageInfo<ResultOrgUserDto> page = new PageInfo<>(ls);

        List<ResultOrgUserDto> orgUserList = page.getList();
        if (orgUserList != null && orgUserList.size() > 0) {
            for (int i = 0; i < orgUserList.size(); i++) {
                ResultOrgUserDto orguser = orgUserList.get(i);
                Users u = usersMapper.selectByPrimaryKey(orguser.getUserId());
                Orgs o = orgsMapper.selectByPrimaryKey(orguser.getOrgId());
                if (u != null && o != null) {
                    orguser.setOrgId(o.getId());
                    orguser.setOrgName(o.getOrgName());
                    orguser.setUserCode(u.getUserCode());
                    orguser.setUserName(u.getUserName());
                    orguser.setEmail(u.getEmail());
                    orguser.setPhone(u.getPhone());
                    orguser.setSex(u.getSex());
                    orguser.setBirthday(u.getBirthday());
                    orguser.setOfficePhone(u.getOfficePhone());
                    orguser.setJobNumber(u.getJobNumber());
                    orguser.setCardNo(u.getCardNo());
                    orguser.setDingUserId(u.getDingUserId());
                    orguser.setUserId(u.getId());
                }
            }
        }
        output.setItems(new PagedResult<ResultOrgUserDto>(orgUserList, (int) page.getTotal()));
        return output;
    }

    public PageLoadOutput PageLoad(PageLoadInput input) throws Exception {
        try {
            PageLoadOutput output = new PageLoadOutput();
            Map<String, OrgDto> parentOrgDtoDic = new HashMap<String, OrgDto>();

            Example exampleApp = new Example(Apps.class);
            Example.Criteria criteria = exampleApp.createCriteria();
            criteria.andEqualTo("UseHrOrg", false);
            List<Apps> apps = appsMapper.selectByExample(exampleApp);


            List<Orgs> orgs = GetOrgTreeList(null, null, false, false);
            List<OrgDto> orgDtos = new ArrayList<OrgDto>();
            if (orgs != null && orgs.size() > 0) {
                for (int i = 0; i < orgs.size(); i++) {
                    OrgDto orgDto = new OrgDto();
                    ObjectUnit.Copy(orgs.get(i), orgDto);

                    if (orgs.get(i).getParentId() == null || !parentOrgDtoDic.containsKey(orgs.get(i).getParentId())) {
                        orgDtos.add(orgDto);
                    } else {
                        OrgDto parentOrgDto = parentOrgDtoDic.get(orgDto.getParentId());
                        if (parentOrgDto.getChildren() == null) {
                            parentOrgDto.setChildren(new ArrayList<OrgDto>());
                        }
                        parentOrgDto.getChildren().add(orgDto);
                    }
                    parentOrgDtoDic.put(orgDto.getId(), orgDto);
                }
            }
            GetOrgUsersOutput outputUser = this.GetOrgUsers(input);
            output.setApps(apps);
            output.setOrgs(orgDtos);
            output.setItems(outputUser.getItems());
            return output;
        } catch (Exception e) {
            throw new ErrorJsonResult("1010203123", e.toString());
        }
    }


    public List<Orgs> GetOrgTreeList(String parentId, String AppCode, boolean withParent, boolean IsMessages) {
        String parentOrgCode = "";
        if (parentId != null && parentId.length() > 0) {
            Orgs parentOrg = orgsMapper.selectByPrimaryKey(parentId);
            parentOrgCode = parentOrg.getOrgIdPath() + "/";
        }
        if (!IsMessages) {
            Example example = new Example(Orgs.class);
            Example.Criteria criteria = example.createCriteria();
            if (AppCode == null) {
                criteria.andIsNull("AppCode");
            } else {
                criteria.andEqualTo("AppCode", AppCode);
            }
            int Count = orgsMapper.selectByExample(example).size();
            if (Count == 0) {
                AppCode = null;
            }
        }

        Example exampleOrg = new Example(Orgs.class);
        Example.Criteria criteria = exampleOrg.createCriteria();
        if (AppCode != null) {
            criteria.andEqualTo("AppCode", AppCode);
        } else {
            criteria.andIsNull("AppCode");
        }
        if (parentId != null && parentId.length() > 0 && withParent) {

            criteria.andCondition(" (Id='" + parentId + "' or OrgIdPath like '" + parentOrgCode + "%') ");
        } else {
            criteria.andLike("OrgIdPath", parentOrgCode + "%");
        }
        exampleOrg.orderBy("OrgIdPath");
        List<Orgs> orgsList = orgsMapper.selectByExample(exampleOrg);
        return orgsList;

    }


    public SearchOrgOutput SearchOrg(SearchOrgInput input) throws Exception {
        SearchOrgOutput output = new SearchOrgOutput();
        List<Orgs> orgs = GetOrgTreeList(null, input.getAppCode(), false, true);

        List<OrgDto> orgDtos = new ArrayList<OrgDto>();
        Map<String, OrgDto> parentOrgDtoDic = new HashMap<String, OrgDto>();

        if (orgs != null && orgs.size() > 0) {
            for (int i = 0; i < orgs.size(); i++) {
                OrgDto orgDto = new OrgDto();
                ObjectUnit.Copy(orgs.get(i), orgDto);

                if (orgs.get(i).getParentId() == null || !parentOrgDtoDic.containsKey(orgs.get(i).getParentId())) {
                    orgDtos.add(orgDto);
                } else {
                    OrgDto parentOrgDto = parentOrgDtoDic.get(orgDto.getParentId());
                    if (parentOrgDto.getChildren() == null) {
                        parentOrgDto.setChildren(new ArrayList<OrgDto>());
                    }
                    parentOrgDto.getChildren().add(orgDto);
                }
                parentOrgDtoDic.put(orgDto.getId(), orgDto);
            }
        }
        //GetOrgUsersInput inputOrgUser = new GetOrgUsersInput();
        //inputOrgUser.setAppCode(input.getAppCode());
        //GetOrgUsersOutput outputOrgUser = this.GetOrgUsers(inputOrgUser);
        output.setOrgs(orgDtos);
        return output;
    }

    public DeleteOrgOutput DeleteOrg(DeleteOrgInput input) {
        DeleteOrgOutput output = new DeleteOrgOutput();

        Orgs curOrg = orgsMapper.selectByPrimaryKey(input.getItem().getId());

        Example exampleOrgChind = new Example(Orgs.class);
        Example.Criteria criteriaOrgChind = exampleOrgChind.createCriteria();
        criteriaOrgChind.andEqualTo("ParentId", input.getItem().getId());
        int countOrgChind = orgsMapper.selectByExample(exampleOrgChind).size();
        if (countOrgChind > 0) {
            throw new ErrorJsonResult("1000031", "有子组织机构，不能删除！");
        }
        Example exampleOrgUser = new Example(OrgUsers.class);
        Example.Criteria criteriaOrgUser = exampleOrgUser.createCriteria();
        criteriaOrgUser.andEqualTo("OrgId", input.getItem().getId());
        int countOrgUsers = orgUsersMapper.selectByExample(exampleOrgUser).size();
        if (countOrgUsers > 0) {
            throw new ErrorJsonResult("1000031", "有用户属于此组织机构，不能删除！");
        }
        orgsMapper.deleteByPrimaryKey(input.getItem().getId());
        return output;
    }

    public CreateOrgOutput CreateOrg(CreateOrgInput input) {
        CreateOrgOutput output = new CreateOrgOutput();

        Example exampleOrg = new Example(Orgs.class);
        Example.Criteria criteriaOrg = exampleOrg.createCriteria();
        criteriaOrg.andEqualTo("OrgCode", input.getItem().getOrgCode());
        if(input.getItem().getAppCode()==null){
            criteriaOrg.andIsNull("AppCode");
        }else{
            criteriaOrg.andEqualTo("AppCode", input.getItem().getAppCode());
        }
        int countOrg = orgsMapper.selectByExample(exampleOrg).size();
        if (countOrg > 0) {
            throw new ErrorJsonResult("1000031", "组织机构编号已存在！");
        }
        String uuid = UUID.randomUUID().toString().replace("-", "").toLowerCase();
        Orgs org = new Orgs();
        org.setId(uuid);
        org.setAppCode(input.getItem().getAppCode());
        org.setOrgCode(input.getItem().getOrgCode());
        org.setOrgName(input.getItem().getOrgName());
        org.setParentId(input.getItem().getParentId());

        if (input.getItem().getParentId() == null || input.getItem().getParentId().length() == 0) {
            org.setOrgIdPath(uuid);
            org.setOrgCodePath(input.getItem().getOrgCode());
            org.setOrgNamePath(input.getItem().getOrgName());
            org.setLevel(1);
        } else {
            Orgs parentOrg = orgsMapper.selectByPrimaryKey(input.getItem().getParentId());
            org.setOrgIdPath(parentOrg.getOrgIdPath() + "/" + uuid);
            org.setOrgCodePath(parentOrg.getOrgCodePath() + "/" + input.getItem().getOrgCode());
            org.setOrgNamePath(parentOrg.getOrgNamePath() + "/" + input.getItem().getOrgName());
            org.setLevel(parentOrg.getLevel() + 1);
        }

        if (input.getItem().getListOrder() == 0) {

            Orgs maxListOrder = orgsMapper.maxListOrder(input.getItem().getParentId());
            if (maxListOrder == null) {
                org.setListOrder(10);
            } else {
                org.setListOrder(maxListOrder.getListOrder() + 10);
            }
        }
        orgsMapper.insertSelective(org);
        output.setItem(org);
        return output;
    }

    public EditOrgOutput EditOrg(EditOrgInput input) throws Exception {
        EditOrgOutput output = new EditOrgOutput();


        Example exampleOrg = new Example(Orgs.class);
        Example.Criteria criteriaOrg = exampleOrg.createCriteria();
        criteriaOrg.andEqualTo("OrgCode", input.getItem().getOrgCode());

        if(input.getItem().getAppCode()==null){
            criteriaOrg.andIsNull("AppCode");
        }else{
            criteriaOrg.andEqualTo("AppCode", input.getItem().getAppCode());
        }
        criteriaOrg.andNotEqualTo("Id", input.getItem().getId());
        int countOrg = orgsMapper.selectByExample(exampleOrg).size();
        if (countOrg > 0) {
            throw new ErrorJsonResult("1000031", "组织机构编号已存在！");
        }


        Orgs oldOrg = orgsMapper.selectByPrimaryKey(input.getItem().getId());
        Boolean isParentChanged = oldOrg.getParentId() != input.getItem().getParentId();
        Boolean isCodeChanged = isParentChanged || oldOrg.getOrgCode() != input.getItem().getOrgCode();
        Boolean isNameChanged = isParentChanged || oldOrg.getOrgName() != input.getItem().getOrgName();

        String oldOrgCodePath = oldOrg.getOrgCodePath();
        String oldOrgNamePath = oldOrg.getOrgNamePath();


        if (input.getItem().getParentId() == null) {
            input.getItem().setOrgIdPath(input.getItem().getId());
            input.getItem().setOrgCodePath(input.getItem().getOrgCode());
            input.getItem().setOrgNamePath(input.getItem().getOrgName());
            input.getItem().setLevel(1);

        } else {
            Orgs parentOrg = orgsMapper.selectByPrimaryKey(input.getItem().getParentId());
            input.getItem().setOrgIdPath(parentOrg.getOrgIdPath() + "/" + input.getItem().getId());
            input.getItem().setOrgCodePath(parentOrg.getOrgCodePath() + "/" + input.getItem().getOrgCode());
            input.getItem().setOrgNamePath(parentOrg.getOrgNamePath() + "/" + input.getItem().getOrgName());
            input.getItem().setLevel(parentOrg.getLevel() + 1);

        }

        if (input.getItem().getListOrder() == 0) {

            Orgs maxListOrder = orgsMapper.maxListOrder(input.getItem().getParentId());
            if (maxListOrder == null) {
                input.getItem().setListOrder(10);
            } else {
                input.getItem().setListOrder(maxListOrder.getListOrder() + 10);
            }
        }

        oldOrg.setParentId(input.getItem().getParentId());
        oldOrg.setOrgCode(input.getItem().getOrgCode());
        oldOrg.setOrgName(input.getItem().getOrgName());
        oldOrg.setOrgIdPath(input.getItem().getOrgIdPath());
        oldOrg.setOrgCodePath(input.getItem().getOrgCodePath());
        oldOrg.setOrgNamePath(input.getItem().getOrgNamePath());
        oldOrg.setListOrder(input.getItem().getListOrder());
        oldOrg.setLevel(input.getItem().getLevel());
        orgsMapper.updateByPrimaryKey(oldOrg);

        if (isCodeChanged) {
            Example exampleOrgUserList = new Example(OrgUsers.class);
            Example.Criteria criteriaOrgUserList = exampleOrgUserList.createCriteria();
            if(input.getItem().getAppCode()==null){
                criteriaOrgUserList.andIsNull("AppCode");
            }else{
                criteriaOrgUserList.andEqualTo("AppCode", input.getItem().getAppCode());
            }
            criteriaOrgUserList.andCondition("CONCAT(OrgCodePath,'/') like '" + oldOrgCodePath + "/%' ");
            List<OrgUsers> curOrgUsers = orgUsersMapper.selectByExample(exampleOrgUserList);
            if (curOrgUsers != null && curOrgUsers.size() > 0) {
                for (int i = 0; i < curOrgUsers.size(); i++) {
                    curOrgUsers.get(i).setOrgCodePath(curOrgUsers.get(i).getOrgCodePath().replace(oldOrgCodePath, input.getItem().getOrgCodePath()));
                    orgUsersMapper.updateByPrimaryKey(curOrgUsers.get(i));
                }
            }
            Example exampleChildOrgList = new Example(Orgs.class);
            Example.Criteria criteriaChildOrgList = exampleChildOrgList.createCriteria();
            if(input.getItem().getAppCode()==null){
                criteriaChildOrgList.andIsNull("AppCode");
            }else{
                criteriaChildOrgList.andEqualTo("AppCode", input.getItem().getAppCode());
            }
            criteriaChildOrgList.andNotEqualTo("Id", input.getItem().getId());
            criteriaChildOrgList.andCondition("CONCAT(OrgCodePath,'/') like '" + oldOrgCodePath + "/%' ");
            List<Orgs> curChildOrgList = orgsMapper.selectByExample(exampleChildOrgList);
            if (curChildOrgList != null && curChildOrgList.size() > 0) {
                for (int i = 0; i < curChildOrgList.size(); i++) {
                    curChildOrgList.get(i).setOrgCodePath(curChildOrgList.get(i).getOrgCodePath().replace(oldOrgCodePath, input.getItem().getOrgCodePath()));
                    orgsMapper.updateByPrimaryKey(curChildOrgList.get(i));
                }
            }
        }
        if (isNameChanged) {
            Example exampleChildOrgList = new Example(Orgs.class);
            Example.Criteria criteriaChildOrgList = exampleChildOrgList.createCriteria();
            if(input.getItem().getAppCode()==null){
                criteriaChildOrgList.andIsNull("AppCode");
            }else{
                criteriaChildOrgList.andEqualTo("AppCode", input.getItem().getAppCode());
            }
            criteriaChildOrgList.andNotEqualTo("Id", input.getItem().getId());
            criteriaChildOrgList.andCondition("CONCAT(OrgNamePath,'/') like '" + oldOrgNamePath + "/%' ");
            List<Orgs> curChildOrgList = orgsMapper.selectByExample(exampleChildOrgList);
            if (curChildOrgList != null && curChildOrgList.size() > 0) {
                for (int i = 0; i < curChildOrgList.size(); i++) {
                    curChildOrgList.get(i).setOrgNamePath(curChildOrgList.get(i).getOrgNamePath().replace(oldOrgNamePath, input.getItem().getOrgNamePath()));
                    orgsMapper.updateByPrimaryKey(curChildOrgList.get(i));
                }
            }
        }
        List<Orgs> orgs = GetOrgTreeList(input.getItem().getId(), input.getItem().getAppCode(), true, false);
        List<OrgDto> orgDtos = new ArrayList<OrgDto>();
        Map<String, OrgDto> parentOrgDic = new HashMap<String, OrgDto>();
        if (orgs != null && orgs.size() > 0) {
            for (int i = 0; i < orgs.size(); i++) {
                OrgDto orgDto = new OrgDto();
                ObjectUnit.Copy(orgs.get(i), orgDto);

                if (orgs.get(i).getParentId() == null || !parentOrgDic.containsKey(orgs.get(i).getParentId())) {
                    orgDtos.add(orgDto);
                } else {
                    OrgDto parentOrgDto = parentOrgDic.get(orgDto.getParentId());
                    if (parentOrgDto.getChildren() == null) {
                        parentOrgDto.setChildren(new ArrayList<OrgDto>());
                    }
                    parentOrgDto.getChildren().add(orgDto);
                }
                parentOrgDic.put(orgDto.getId(), orgDto);
            }
        }
        output.setItem(oldOrg);
        return output;
    }
    public ChangeAccountStatusOutput ChangeAccountStatus(ChangeAccountStatusInput input) {
        ChangeAccountStatusOutput output = new ChangeAccountStatusOutput();

        Users user = null;
        if(!isBlank(input.getId())){
            user=usersMapper.selectByPrimaryKey(input.getId());
        }

        if(!isBlank(input.getUserCode())){
            user=usersMapper.getUsersByUserCode(input.getUserCode());
        }

        if(user==null){
            throw new ErrorJsonResult("1000031","找不到用户！");
        }

        user.setAccountIsDisabled(input.getAccountIsDisabled());

      output.setItem(user);

        return output;
    }


}
